<template>
  <el-form :model="spuInfo" :rules="spuRules" ref="spuFormRef" label-width="100px">
    <el-form-item label="SPU名称" prop="spuName">
      <el-input v-model="spuInfo.spuName" placeholder="SPU名称"></el-input>
    </el-form-item>
    <el-form-item label="SPU品牌" prop="tmId">
      <el-select v-model="spuInfo.tmId" placeholder="请选择">
        <el-option :label="tm.tmName" :key="tm.id" v-for="tm in trademarkList" :value="tm.id" />
      </el-select>
    </el-form-item>
    <el-form-item label="SPU描述" prop="description">
      <el-input v-model="spuInfo.description" type="textarea" :rows="3" placeholder="SPU描述"></el-input>
    </el-form-item>
    <el-form-item label="SPU图片" prop="spuImageList">
      <el-upload v-model:file-list="spuInfo.spuImageList" :action="`${BASE_URL}/admin/product/fileUpload`" list-type="picture-card" :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
        <el-icon>
          <Plus />
        </el-icon>
      </el-upload>

      <el-dialog v-model="dialogVisible">
        <img w-full :src="dialogImageUrl" alt="Preview Image" />
      </el-dialog>
    </el-form-item>
    <el-form-item label="销售属性" prop="spuSaleAttrList">
      <el-select v-model="spuInfo.spuSaleAttr" :placeholder="`还有${filterBaseSaleAttrList.length}个未选择`">
        <el-option :label="bsa.name" :key="bsa.id" v-for="bsa in filterBaseSaleAttrList" :value="bsa.name" />
      </el-select>
      <el-button :icon="Plus" type="primary" style="margin-left:10px" @click="addSpuSaleAttr">添加销售属性</el-button>
      <el-table border :data="spuInfo.spuSaleAttrList" style="margin:10px 0">
        <el-table-column label="序号" type="index" align="center" width="80px"></el-table-column>
        <el-table-column label="属性名" prop="saleAttrName" width="150px"></el-table-column>
        <el-table-column label="属性值名称列表">
          <template v-slot="{row,$index}">
            <el-tag v-for="tag in row.spuSaleAttrValueList" :key="tag" class="mx-1" closable :disable-transitions="false" style="margin-right:6px" @close="handleClose(tag,row)">
              {{ tag.saleAttrValueName }}
            </el-tag>
            <el-input v-if="row.inputVisible" ref="InputRef" v-model="inputValue" class="ml-1 w-20" size="small" @keyup.enter="handleInputConfirm(row)" @blur="handleInputConfirm(row)" style="width:80px" />
            <el-button v-else :icon="Plus" type="primary" class="button-new-tag ml-1" size="small" @click="showInput(row)">
            </el-button>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{row,$index}">
            <el-popconfirm title="确定要删除此属性吗?" @confirm="deleteSaleAttr($index)">
              <template #reference>
                <el-button :icon="Delete" type="danger" size="small"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitSpuForm(spuFormRef)">保存</el-button>
      <el-button @click="emits('changeScene',1)">取消</el-button>
    </el-form-item>
  </el-form>
</template>

<script lang="ts">
export default {
  name: 'SpuForm'
};
</script>
<script lang="ts" setup>
import { ref, onMounted, reactive, computed, nextTick } from 'vue';
import { Plus, Edit, Delete } from '@element-plus/icons-vue';
import { ElMessage, ElInput } from 'element-plus';
import type { FormInstance, FormRules, UploadProps, UploadUserFile } from 'element-plus';
import { reqGetTrademarkListData, reqGetBaseSaleAttrListData, reqSaveSpuInfo, reqGetSpuImageList, reqGetSpuSaleAttrList, reqUpdateSpuInfo } from '@/api/product/spu';
import { useCategorySelectorInfoStore } from '@/stores/categorySelector';
const categoryStore = useCategorySelectorInfoStore();
const BASE_URL = import.meta.env.VITE_API_URL;
const fileList = ref<UploadUserFile[]>([]);

//接收传递过来的自定义事件
const emits = defineEmits(['changeScene']);
const props = defineProps(['currentSpuInfo', 'aaa', 'bbb']);
console.log('pr', props);

const spuFormRef = ref<FormInstance>();
//以下四个属性是与销售属性值相关的
const inputValue = ref('');
// const dynamicTags = ref(['Tag 1', 'Tag 2', 'Tag 3']);
const inputVisible = ref(false);
const InputRef = ref<InstanceType<typeof ElInput>>();
// 定义一个SpuInfo对象的数据
const spuInfo = reactive({
  spuName: '', // spu名称
  tmId: '', // 品牌
  description: '', // 品牌描述
  spuImageList: [
    //  "imgName": "string",
    //   "imgUrl": "string",
  ], // 收集的要上传的图片
  spuSaleAttrList: [], // 销售属性
  category3Id: '', // 三级分类id
  spuSaleAttr: '', //用于获取要添加的属性名 此值不需要发送给服务器
  ...props.currentSpuInfo
});

const dialogImageUrl = ref('');
const dialogVisible = ref(false);
// 页面中一开始挂载时就需要渲染出来的数据  品牌列表  销售属性列表
const trademarkList = ref([]);
const baseSaleAttrList = ref([]);

// 0. 提交前添加一个校验规则
const spuRules = reactive<FormRules>({
  spuName: [
    { required: true, message: '请输入spu名称', trigger: 'blur' },
    { min: 1, max: 20, message: '名字长度在1---20之间', trigger: 'blur' }
  ],
  tmId: [
    {
      required: true,
      message: '请选择对应的品牌',
      trigger: 'change'
    }
  ],
  description: [
    {
      required: true,
      message: '请输入spu名称描述',
      trigger: 'blur'
    }
  ],
  spuImageList: [
    {
      type: 'array',
      required: true,
      message: '请至少上传一张图片',
      trigger: 'change'
    }
  ],
  spuSaleAttrList: [
    {
      type: 'array',
      required: true,
      message: '请至少添加一个属性',
      trigger: 'change'
    }
  ]
});

// 1. 页面组件挂载完毕后就要发送请求，获取对应的数据
onMounted(async () => {
  // const tradeResult = await reqGetTrademarkListData()
  // const baseSaleResult = await reqGetBaseSaleAttrListData()
  let promies = [reqGetTrademarkListData(), reqGetBaseSaleAttrListData()];
  console.log(spuInfo.id);
  if (spuInfo.id) {
    //此时是编辑操作，需要获取图片列表和销售属性列表数据
    promies = promies.concat([reqGetSpuImageList(spuInfo.id), reqGetSpuSaleAttrList(spuInfo.id)]);
  }
  try {
    // Promise.race()  赛跑形式的请求 谁快就先用谁
    // Promise.allSettled() 允许有失败的请求
    const [responseTrademarkList, responseBaseSaleAttrList, responseSpuImageList, responseSpuSaleAttrList] = await Promise.all(promies);

    // console.log('all',responseTrademarkList,responseBaseSaleAttrList)
    trademarkList.value = responseTrademarkList;
    baseSaleAttrList.value = responseBaseSaleAttrList;
    // console.log(responseSpuImageList, responseSpuSaleAttrList);
    if (responseSpuImageList && responseSpuSaleAttrList) {
      spuInfo.spuImageList = responseSpuImageList.map(item => {
        return {
          ...item, //为了将来更新时使用，最好将服务端响应回来的数据也带着
          name: item.imgName,
          url: item.imgUrl
        };
      });
      spuInfo.spuSaleAttrList = responseSpuSaleAttrList;
    }
  } catch (error) {
    ElMessage.error('获取品牌数据及销售属性失败...');
  }
});

// 图片上传相关
// 2. 图片上传之前的格式校验
const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => {
  const imgArr = ['image/jpeg', 'image/png', 'image/jpg'];
  if (!imgArr.includes(rawFile.type)) {
    ElMessage.error('图片格式不正确,应该是.jpg/.png/.jpeg等');
    return false;
  } else if (rawFile.size / 1024 / 1024 > 2) {
    ElMessage.error('图片大小不能超过2M,请重新上传...');
    //1T > 1024 G= 1024M > 1024K >1024B
    return false;
  }
  return true;
};
// 3. 上传图片成功后的操作
const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile, uploadFiles) => {
  console.log(response, uploadFile, uploadFiles);
  // imageUrl.value = URL.createObjectURL(uploadFile.raw!);
  spuInfo.spuImageList = uploadFiles;
  // spuInfo.spuImageList.push({
  //   name: uploadFile.name,
  //   url: response.data || uploadFile.url
  // });
  // 清除之前的图片校验规则
  // ruleFormRef.value?.clearValidate(['logoUrl'])
  //清除之前的图片校验规则
  spuFormRef.value?.clearValidate(['spuImageList']);
};

// 4. 删除图片
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  // uploadFile 被删除的那张图片
  // uploadFiles 剩余的未经删除的图片 是一个数组
  spuInfo.spuImageList = uploadFiles;
};
// 5. 预览图片时的函数
const handlePictureCardPreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
//6.添加销售属性
const addSpuSaleAttr = () => {
  //6.1 如果前一个属性的属性值为空的话不要添加新属性
  const spuSaleAttrList = spuInfo.spuSaleAttrList;
  const flag = spuSaleAttrList.length && spuSaleAttrList.some(item => item.spuSaleAttrValueList.length === 0);
  if (flag) return ElMessage.error('有属性值为空，请添加。。。');

  const id = baseSaleAttrList.value.find(item => item.name === spuInfo.spuSaleAttr).id;

  spuInfo.spuSaleAttrList.push({
    baseSaleAttrId: id,
    inputVisible: false,
    saleAttrName: spuInfo.spuSaleAttr,
    spuSaleAttrValueList: [] //用于收集属性值
  });
  //清空下拉框
  spuInfo.spuSaleAttr = '';
};

//7.使用计算属性 实现添加销售属性时移除效果
const filterBaseSaleAttrList = computed(() => {
  return baseSaleAttrList.value.filter(item => {
    return !spuInfo.spuSaleAttrList.find(obj => item.name == obj.saleAttrName);
  });
});

//8.删除列表中的销售属性
const deleteSaleAttr = (index: number) => {
  spuInfo.spuSaleAttrList.splice(index, 1);
};

//9.删除某属性值时的函数
const handleClose = (tag: string, row) => {
  console.log('cc', tag, row);
  row.spuSaleAttrValueList.splice(row.spuSaleAttrValueList.indexof(tag), 1);
};
//10.单击添加属性值按钮时的切换需要用到的函数
const showInput = row => {
  row.inputVisible = true;
  nextTick(() => {
    InputRef.value!.input!.focus();
  });
};
//11.实现属性值添加时的函数
const handleInputConfirm = row => {
  if (inputValue.value) {
    //如果新添的属性值和之前有的重复就不添加
    const result = row.spuSaleAttrValueList.some(item => item.saleAttrValueName === inputValue.value);
    if (result) {
      ElMessage.error('此属性已添加过了，请更换。。。');
      row.inputVisible = false;
      inputValue.value = '';
      return;
    }
    row.spuSaleAttrValueList.push({
      baseSaleAttrId: row.baseSaleAttrId,
      isChecked: '0',
      saleAttrName: row.saleAttrName,
      saleAttrValueName: inputValue.value
    });
  }
  row.inputVisible = false;
  inputValue.value = '';
};

//12.提交spuForm中数据时调用的函数
const submitSpuForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      //在这再次进行图片数据和销售属性数据的细节化处理，对销售属性的属性值再做一次判断，没有属性值的话就不用发送请求
      const spuSaleAttrList = spuInfo.spuSaleAttrList;
      const flag = spuSaleAttrList.length && spuSaleAttrList.some(item => item.spuSaleAttrValueList.length === 0);
      if (flag) return ElMessage.error('销售属性的属性值有空值，请检查。。。');
      // 添加category3Id
      spuInfo.category3Id = categoryStore.category3Id as number;
      //将上传的图片列表处理一下，一定要有imgName imgUrl两个属性
      spuInfo.spuImageList = spuInfo.spuImageList.map(item => {
        return {
          imgName: item.name,
          imgUrl: item.response?.data || item.url
        };
      });
      if (spuInfo.id) {
        // 此时是更新操作
        await reqUpdateSpuInfo(spuInfo);
        ElMessage.success('更新spu成功');
      } else {
        const result = await reqSaveSpuInfo(spuInfo);
        ElMessage.success('添加spu成功');
      }
      emits('changeScene', 1);
    } else {
      console.log('error submit', fields);
    }
  });
};
</script>
<style>
</style>